package com.briup.emdc.server.impl;

import com.briup.emdc.bean.Env;
import com.briup.emdc.config.Backup;
import com.briup.emdc.config.Configuration;
import com.briup.emdc.config.Log;
import com.briup.emdc.server.DBStore;
import com.briup.emdc.server.Server;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.Properties;

/**
 * @author Kevin
 * @since 2024.04.10
 **/
public class ServerImpl implements Server{
    private Log log;
    private DBStore store;
    private Backup backup;
    private int serverPort;
    private String serverBackupPath;

    public void startServer(){
        try(ServerSocket ss=new ServerSocket(serverPort)){
            log.info("服务器启动了...");
            while(true){
                Socket cs=ss.accept();
                InetAddress ia=cs.getInetAddress();
                String ip=ia.getHostAddress();
                int port=cs.getPort();
                log.info("客户端连接至服务器了，IP为："+ip+", 端口为："+port);

                new Thread(()->{
                    Collection<Env> envs=null;
                    try{
                        // 将之前入库时备份的数据
                        // 先加载进来进行合并之后再入库
                        Collection<Env> envs1=backup.load(serverBackupPath,false);
                        InputStream is=cs.getInputStream();
                        envs=this.reciver(is);
                        envs.addAll(envs1);
                        envs.forEach(System.out::println);
                        // 调用入库模块对集合中的元素持久化保存
                        store.saveDb(envs);
                    }catch(Exception e){
                        log.error(e.getMessage());
                        // 对入库失败时的对象做备份
                        if(envs!=null){
                            try{
                                backup.save(envs,serverBackupPath,false);
                            }catch(Exception ex){
                                log.error(ex.getMessage());
                            }
                        }
                    }
                }).start();
            }
        }catch(Exception e){
            log.error(e.getMessage());
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Collection<Env> reciver(InputStream is) throws Exception{
        log.warn("进行类型转换。");
        return (Collection<Env>)new ObjectInputStream(is).readObject();
    }

    @Override
    public void shutdown(){
    }

    @Override
    public void init(final Properties prop){
        serverPort=Integer.parseInt(prop.getProperty("server-port"));
        serverBackupPath=prop.getProperty("server-backup-path");
    }

    @Override
    public void configure(final Configuration conf) throws Exception{
        this.log=conf.getLogger();
        this.store = conf.getDbStore();
        this.backup = conf.getBackup();
    }
}
